#include "scanresultswidget.h"

// Qt Includes
#include <QFileInfo>
#include <QListWidgetItem>
#include <QVBoxLayout>

// Local Includes
#include "resultdetailwidget.h"
#include "scanresults.h"

// Constants
const int gc_nContextComboIndexSeverities = 0;
const int gc_nContextComboIndexPlugins = 1;
const int gc_nContextComboIndexFiles = 2;

/////////////////////////////////////////////////////////////////////
// Construction & Destruction
/////////////////////////////////////////////////////////////////////
CScanResultsWidget::CScanResultsWidget(QWidget *pParent/* = NULL*/, Qt::WFlags windowFlags/* = 0*/)
	: QWidget(pParent, windowFlags),
	  m_pScanResults(NULL)
{
	setupUi(this);

	// Signals & Slots.
	connect(m_pContextCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onContextComboCurrentIndexChanged(int)));
	connect(m_pContextListWidget, SIGNAL(currentRowChanged(int)), this,
			SLOT(onContextListWidgetCurrentRowChanged(int)));

	// Initially, we have no results.
	m_pContextSummaryLabel->setVisible(false);
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Member Functions
/////////////////////////////////////////////////////////////////////
void CScanResultsWidget::setScanResults(CScanResults* pScanResults)
{
	m_pScanResults = pScanResults;
	onContextComboCurrentIndexChanged(m_pContextCombo->currentIndex());
}

void CScanResultsWidget::switchToSeveritiesContext()
{
	if(!m_pScanResults)
		return;

	QList<quint8> lstSeverities = m_pScanResults->getSeverities();
	const int nSeverityCount = lstSeverities.count();

	for(int i = 0; i < nSeverityCount; i++)
	{
		QListWidgetItem *pListWidgetItem = new QListWidgetItem(
				QString::number(lstSeverities.at(i)), m_pContextListWidget);

		pListWidgetItem->setData(Qt::UserRole, lstSeverities.at(i));
		pListWidgetItem->setIcon(QIcon(":/Icons/Severity"));
	}
}

void CScanResultsWidget::switchToPluginsContext()
{
	if(!m_pScanResults)
		return;

	QList<NScanResultRecords::PluginRecord> lstPlugins = m_pScanResults->getPlugins(false);
	const int nPluginCount = lstPlugins.count();

	for(int i = 0; i < nPluginCount; i++)
	{
		QListWidgetItem *pListWidgetItem = new QListWidgetItem(
				lstPlugins.at(i).name, m_pContextListWidget);

		pListWidgetItem->setData(Qt::UserRole, lstPlugins.at(i).id);
		pListWidgetItem->setIcon(QIcon(":/Icons/FileScanner"));
		pListWidgetItem->setToolTip(lstPlugins.at(i).desc);
	}
}

void CScanResultsWidget::switchToFilesContext()
{
	if(!m_pScanResults)
		return;

	QList<NScanResultRecords::FileRecord> lstFiles = m_pScanResults->getFiles(false);
	const int nFileCount = lstFiles.count();

	for(int i = 0; i < nFileCount; i++)
	{
		QListWidgetItem *pListWidgetItem = new QListWidgetItem(
				lstFiles.at(i).name, m_pContextListWidget);

		pListWidgetItem->setData(Qt::UserRole, lstFiles.at(i).id);

		const QFileInfo theFileInfo(lstFiles.at(i).name);

		if(theFileInfo.suffix().toLower() == "h")
		{
			pListWidgetItem->setIcon(QIcon(":/Icons/File_H"));
		}
		else if(theFileInfo.suffix().toLower() == "cpp")
		{
			pListWidgetItem->setIcon(QIcon(":/Icons/File_CPP"));
		}
	}
}

void CScanResultsWidget::clearResults()
{
	QLayout *pResultsWidgetLayout = m_pResultsWidget->layout();

	if(!pResultsWidgetLayout)
		return;

	QLayoutItem *pLayoutItem = NULL;

	while(NULL != (pLayoutItem = pResultsWidgetLayout->takeAt(0)))
	{
		pResultsWidgetLayout->removeItem(pLayoutItem);

		delete pLayoutItem->widget();
		delete pLayoutItem;
	}
}

void CScanResultsWidget::showResults(const QList<NScanResultRecords::ResultRecord> &lstResults)
{
	const int nSelContextIndex = m_pContextCombo->currentIndex();
	const bool bShowFileName = (nSelContextIndex != gc_nContextComboIndexFiles);
	const bool bShowPluginName = (nSelContextIndex != gc_nContextComboIndexPlugins);
	const bool bShowSeverity = (nSelContextIndex != gc_nContextComboIndexSeverities);
	QLayout *pResultsWidgetLayout = m_pResultsWidget->layout();

	if(!pResultsWidgetLayout)
	{
		m_pResultsWidget->setLayout(new QVBoxLayout(this));
		pResultsWidgetLayout =  m_pResultsWidget->layout();
	}

	QMap<quint32, NScanResultRecords::PluginRecord> mapPlugins;
	QMap<quint32, NScanResultRecords::FileRecord> mapFiles;
	const int nResultCount = lstResults.count();

	for(int i = 0; i < nResultCount; i++)
	{
		CResultDetailWidget *pResultsDetailWidget = new CResultDetailWidget(this);
		NScanResultRecords::FileRecord theFileRecord;
		NScanResultRecords::PluginRecord thePluginRecord;

		if(mapFiles.contains(lstResults.at(i).fileId))
		{
			theFileRecord = mapFiles.value(lstResults.at(i).fileId);
		}
		else
		{
			theFileRecord = m_pScanResults->getFileByID(lstResults.at(i).fileId);
		}

		if(mapPlugins.contains(lstResults.at(i).pluginId))
		{
			thePluginRecord = mapPlugins.value(lstResults.at(i).pluginId);
		}
		else
		{
			thePluginRecord = m_pScanResults->getPluginByID(lstResults.at(i).pluginId);
		}

		if(bShowFileName)
		{
			pResultsDetailWidget->setFileName(theFileRecord.name);
		}

		if(bShowPluginName)
		{
			pResultsDetailWidget->setPluginDetails(thePluginRecord.name, thePluginRecord.desc);
		}

		if(bShowSeverity)
		{
			pResultsDetailWidget->setSeverity(lstResults.at(i).severity);
		}

		pResultsDetailWidget->setCode(lstResults.at(i).code);

		pResultsWidgetLayout->addWidget(pResultsDetailWidget);
	}

	// TODO: Make this less dodgy. ;)
	((QVBoxLayout*)pResultsWidgetLayout)->addStretch();
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Private Slots
/////////////////////////////////////////////////////////////////////
void CScanResultsWidget::onContextComboCurrentIndexChanged(int nIndex)
{
	m_pContextListWidget->clear();
	clearResults();

	QString strContextHint;

	switch(nIndex)
	{
		case gc_nContextComboIndexSeverities:
		{
			switchToSeveritiesContext();
			strContextHint = "%1 Severities";
			break;
		}

		case gc_nContextComboIndexPlugins:
		{
			switchToPluginsContext();
			strContextHint = "%1 Plugins";
			break;
		}

		case gc_nContextComboIndexFiles:
		{
			switchToFilesContext();
			strContextHint = "%1 Files";
			break;
		}
	}

	if(!strContextHint.isEmpty())
	{
		m_pContextSummaryLabel->setText(strContextHint.arg(m_pContextListWidget->count()));
		m_pContextSummaryLabel->setVisible(true);
	}
}

void CScanResultsWidget::onContextListWidgetCurrentRowChanged(int nRow)
{
	clearResults();

	const QListWidgetItem *pListWidgetItem = m_pContextListWidget->item(nRow);

	if(!pListWidgetItem)
		return;

	QList<NScanResultRecords::ResultRecord> lstResults;

	switch(m_pContextCombo->currentIndex())
	{
		case gc_nContextComboIndexSeverities:
		{
			lstResults = m_pScanResults->getResultsBySeverity(pListWidgetItem->data(Qt::UserRole).toUInt());
			break;
		}

		case gc_nContextComboIndexPlugins:
		{
			lstResults = m_pScanResults->getResultsByPluginID(pListWidgetItem->data(Qt::UserRole).toUInt());
			break;
		}

		case gc_nContextComboIndexFiles:
		{
			lstResults = m_pScanResults->getResultsByFileID(pListWidgetItem->data(Qt::UserRole).toUInt());
			break;
		}
	}

	showResults(lstResults);
}
/////////////////////////////////////////////////////////////////////
